﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using AutoMapper;
using Enferno.Public.Web.Models;
using Enferno.StormApiClient.Products;
using Enferno.Web.StormUtils;

namespace Enferno.Public.Web.Mappers.Resolvers
{
    public abstract class ProductFilesBaseResolver<TProductFileModel> : ValueResolver<Product, IEnumerable<TProductFileModel>>
        where TProductFileModel: ProductFileModel, new()
    {
        protected IEnumerable<TProductFileModel> ResolveBase(Product product, ProductFileType fileType)
        {
            var fileList = new List<TProductFileModel>();

            if (product.ImageKey.HasValue) fileList.Add(new TProductFileModel { Type = (int)fileType, Url = Link.ImageUrl(product.ImageKey.ToString()), AltText = product.Name});

            return MapFiles(product, fileList);
        }  

        protected static IEnumerable<TProductFileModel> MapFiles(Product product, List<TProductFileModel> fileList)
        {
            if (product.Files == null || product.Files.Count <= 0) return fileList;

            foreach (var file in product.Files)
            {
                var url = file.Type == (int) FileType.Embedded
                    ? file.Path
                    : Link.ImageUrl(file.Key.ToString(), GetFileExtension(file.Type));

                if (!fileList.Exists(f => f.Url == url))
                {
                    fileList.Add(new TProductFileModel
                    {
                        Type = file.Id,
                        Url = url,
                        AltText = file.Name ?? product.Name
                    });
                }
            }

            return fileList;
        }

        private static string GetFileExtension(int fileType)
        {
            if (Enum.IsDefined(typeof(FileType), fileType))
            {
                return ((FileType)fileType).ToString().ToLower();
            }
            return Enum.IsDefined(typeof(ExternalFileType), fileType) ? ((ExternalFileType)fileType).ToString().ToLower() : "";
        }

    }

    public class ProductFilesResolver<TProductFileModel> : ProductFilesBaseResolver<TProductFileModel>
        where TProductFileModel: ProductFileModel, new()
    {
        protected override IEnumerable<TProductFileModel> ResolveCore(Product product)
        {
            return ResolveBase(product, ProductFileType.DefaultImage);
        }     
    }

    public class VariantFilesResolver<TProductFileModel> : ProductFilesBaseResolver<TProductFileModel>
        where TProductFileModel: ProductFileModel, new()
    {
        protected override IEnumerable<TProductFileModel> ResolveCore(Product product)
        {
            return ResolveBase(product, ProductFileType.VariantImage);
        }
    }

    public abstract class ProductItemFilesBaseResolver<TProductFileModel> : ValueResolver<ProductItem, IEnumerable<TProductFileModel>>
        where TProductFileModel: ProductFileModel, new()
    {
        protected IEnumerable<TProductFileModel> ResolveBase(ProductItem productItem, ProductFileType fileType)
        {
            var fileList = new List<TProductFileModel>();

            if (productItem.ImageKey.HasValue) fileList.Add(new TProductFileModel { Type = (int)fileType, Url = Link.ImageUrl(productItem.ImageKey.ToString()), AltText = productItem.Name });

            return MapFiles(productItem, fileList);
        }

        protected static IEnumerable<TProductFileModel> MapFiles(ProductItem productItem, List<TProductFileModel> fileList)
        {
            if (string.IsNullOrWhiteSpace(productItem.AdditionalImageKeySeed) || !productItem.AdditionalImageKeySeed.Split(',').Any()) return fileList;
            foreach (var imageKey in productItem.AdditionalImageKeySeed.Split(','))
            {
                var parts = imageKey.Split(':');
                var id = parts[0];
                var key = parts[1];
                var url = Link.ImageUrl(key, "jpg");
                if (!fileList.Exists(f => f.Url == url))
                {
                    fileList.Add(new TProductFileModel{ Type = int.Parse(id), Url = url, AltText = productItem.Name}); 
                }
            }
            return fileList;
        }   
    }

    public class ProductItemFilesResolver<TProductFileModel> : ProductItemFilesBaseResolver<TProductFileModel>
        where TProductFileModel: ProductFileModel, new()
    {
        protected override IEnumerable<TProductFileModel> ResolveCore(ProductItem productItem)
        {
            return ResolveBase(productItem, ProductFileType.DefaultImage);
        }
    }

    public class VariantItemFilesResolver<TProductFileModel> : ProductItemFilesBaseResolver<TProductFileModel>
        where TProductFileModel: ProductFileModel, new()
    {
        protected override IEnumerable<TProductFileModel> ResolveCore(ProductItem productItem)
        {
            return ResolveBase(productItem, ProductFileType.VariantImage);
        }
    }
}
